/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.vsu.csf.qasystem.syntax;

import java.util.ArrayList;
import java.util.List;
import ru.vsu.csf.qasystem.morph.Lexem;
import ru.vsu.csf.qasystem.morph.Punkt;
import ru.vsu.csf.qasystem.morph.Word;
import ru.vsu.csf.qasystem.morph.enumtypes.PunktType;
import ru.vsu.csf.qasystem.syntax.templates.AbstractTemplate;
import ru.vsu.csf.qasystem.syntax.templates.OrTemplate;
import ru.vsu.csf.qasystem.syntax.templates.PartTemplate;
import ru.vsu.csf.qasystem.syntax.templates.PunktTemplate;
import ru.vsu.csf.qasystem.syntax.templates.WordTemplate;

/**
 * Синтаксический анализатор.
 * @author Руслан
 */
public class SyntaxParser {
    
    private List<List<Lexem>> parts;
    
    public Sentence parse(List<List<Lexem>> parts) {
        this.parts = parts;
        Sentence sentence = new Sentence();
        SentenceType stype = determineSentenseType();
        sentence.setType(stype);
        
        return null;
    }
    
    private SentenceType determineSentenseType() {
        return SentenceType.Narrative;
    }
    
    private List<SyntaxElement> parseTemplate(Integer lexemIndex, AbstractTemplate template) {
        if(template.getClass().equals(PartTemplate.class)) {
           PartTemplate partTemp = (PartTemplate)template;
           return parsePartTemplate(new SyntaxElement(), lexemIndex, partTemp, 0);
        }
        if(template.getClass().equals(OrTemplate.class)) {
            OrTemplate orTemp = (OrTemplate) template;
            List<SyntaxElement> res = new ArrayList<SyntaxElement>();
            for (AbstractTemplate temp : orTemp.getTemplates()) {
                res.addAll(parseTemplate(0,temp));
            }
            return res;
        }
        if (lexemIndex >= parts.size()) {
                return new ArrayList<SyntaxElement>();
        }
        if(template.getClass().equals(WordTemplate.class)) {
            WordTemplate wTemp = (WordTemplate) template;
            
            List<SyntaxElement> res = new ArrayList<SyntaxElement>();
            for (Lexem l : parts.get(lexemIndex)) {
                if (l.getClass() == wTemp.getType()) {
                    res.add(new SyntaxElement((Word)l));
                }
            }
        }
        if(template.getClass().equals(PunktTemplate.class)) {
            PunktTemplate pTemp = (PunktTemplate)template;
            Lexem l = parts.get(lexemIndex).get(0);
            Punkt p = (Punkt) l;
            if(p.getType() == pTemp.getType()) {
                
            }
        }
        return null;
    }
    
    private List<SyntaxElement> parsePartTemplate(SyntaxElement element, 
            Integer lexemIndex, PartTemplate template, int templateIndex) {
        List<SyntaxElement> result = new ArrayList<SyntaxElement>();
        if (lexemIndex >= parts.size()) return result;
        if (templateIndex >= template.getTemplates().size()) {
            result.add(element);
            return result;
        }
        List<SyntaxElement> res = parseTemplate(0,template.getTemplates().get(templateIndex));
        for (SyntaxElement elem : res) {
             SyntaxElement el = element.clone();
             if (template.getTemplates().get(templateIndex).getIsMain()) {
                 el.setValue(elem.getValue());
                 el.setChildren(elem.getChildren());
             }
             else {
                 el.addChild(elem);
             }
             result.addAll(parsePartTemplate(el,0,template,templateIndex + 1));
        }
        return result;
    }
    

}
